iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 29
1
Modern Web

美麗的邂逅-與安室....伊春系列 第 29

傳而習乎 (JDBC/JPA/Hibernate/MyBatis)

  • 分享至 

  • xImage
  •  
吾日三省吾身,為人謀而不忠乎,與朋友交而不信乎,傳不習乎?
  • JDBC (jdbcTemplate)
  • JPA / Hibernat (JpaRepository, @Column)
  • MyBatis (@Mapper)

這一回是有點偷懶了,工作起來其實是沒有假日的,工作遭遇的問題,會在假日試圖解決,因此,也就沒有時間寫文章了,所以偷懶一下。大家也可以輕鬆看。在上幾回中,我們或是直接用 JDBC,或是用 JPA, MyBatis (如果讀者沒有看過前幾回,又不了解 JDBC, JPA, MyBatis,建議先閱讀前幾回再回到這裡,當然,如果讀者天資聰穎,才貌雙全 /* 應該與 “貌” 無關!*/,也是可以直接閱讀這一回), 在這裡我們並舉對照加以比較,這三種作法,是對資料庫的編碼不同,主要差別在 Respository (Dao), 我們就比對這個檔案,其他的檔案,在這裡就忽略不看,如果大家想知道細節,可以翻回去看。
只討論兩個函式,一個是findAll(), 一個是 userAdd(), 如果直接使用 JDBC

private JdbcTemplate jdbcTemplate;
public void userAdd(User user) {
	String sql_format= ("insert into users(name,email) value(?,?)";
	jdbcTemplate.update(sql_format,user.getName(),user.getEmail());
}	
public List<User> findAll() {
	String sql= "select id,name,email from users";
	return jdbcTemplate.query(sql, (rs, rowNum) -> new User(rs.getString("name"),rs.getString("email")));	
}

控制得最仔細,欄位的對應是 "手動" 的,findAll() 也可以寫成

public List<User> findAll() {
	String sql=String.format("select id,name,email from %s", USERS);
	List<User> users = jdbcTemplate.query(sql, new UserRowMapper());
	return users;		
}

而 RowMapper 是獨立的類別,適合欄位較多的狀況。

public class UserRowMapper implements RowMapper<User> {
	public User mapRow(ResultSet rs, int rowNum) throws SQLException {
		User user = new User();
		user.setId(new Integer(rs.getInt("id")));
		user.setName(rs.getString("name"));
		user.setEmail(rs.getString("email"));
		return user;
	}

接著我們看一下JPA/Hibernate

public interface IUserRepository extends JpaRepository<User,Long>  {
	List<User> findAll();
}

繼承自 JpaRepository,findAll() 函式一行搞定,沒有 SQL,沒有欄位對應,一切就成了,但是 userAdd() 不見了,使用時改用 save(),使用方法相同 (當然,把 save() 再外裹一層,變成 userAdd() 也是合法的)。這就是成衣的概念,拿起來就可以穿,但是有些東西是事先依模子作好的,口袋有幾個,位置在何處…。到了 MyBatis,似乎介於兩個中間。

    @Update("INSERT INTO USERS(name,email) VALUES(#{user.name}, #{user.email})")
	void userAdd(@Param("user") User user);
    
    @Select("SELECT * FROM users")
	List<User> findAll();

需要 SQL 指令,但是不需要處理欄位對應關係(其實是己經寫入SQL指令之中)。不管是 Hibernate 或是 MyBatis 編寫的都是界面 (Interface), 只有函式的宣告,而不需要定義函式執行的邏輯,至於JDBC則是類別(class)。欄位的對應關係 JPA/Hibernate是寫在模型(Model)(JDBC 是手動對照, MyBatis 若是資料庫欄位名稱與類別相同則不必定義,若不相同,請參考上一回),就如例中 User 類別:

@Id
@GeneratedValue(strategy = IDENTITY)
@Column(name="ID")
private long id;
    
@Column(name="NAME")
private String name;
    
@Column(name="EMAIL")
private String email;

若是如範例,資料庫欄位名稱與類別名稱相同,@Column一行亦可省略。
處理資料庫是應用程式不可或缺的一塊,工具的特點就是方便,模組化的特色是穩藏內部細節(使用者不必知道SQL語法)透過 Spring Boot 可以輕輕鬆鬆完成許多以往必須花費許多精神完成的事,然而,工具的日新月異,而且歧路亡羊,在精進的路上,就要深思慎選,為學要如金字塔,要能博大要能高。


上一篇
管教 (MyBatis)
下一篇
後記 (to be continued)
系列文
美麗的邂逅-與安室....伊春30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言